package cn.coisini.security;

import cn.coisini.model.vo.RouterVo;
import cn.coisini.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author xiangshaw
 * Description:
 */
@Service
@RequiredArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {

    private final UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1.查询用户信息
        Map<String, Object> userMap = userService.findByUsername(username);
        // 2.检查用户
        if (userMap == null) {
            throw new UsernameNotFoundException("未找到用户名为: " + username + " 的用户");
        }
        // 3.从 map 中获取用户名和密码
        String authUserName = (String) userMap.get("username");
        String password = (String) userMap.get("password");
        if (authUserName == null || password == null) {
            throw new UsernameNotFoundException("用户名: " + username + " 的用户详细信息未找到");
        }
        // 4.获取用户的权限列表
        List<GrantedAuthority> authorities = getUserAuthorities(userMap);
        // 5.构建并返回 UserDetails 对象
        return new org.springframework.security.core.userdetails.User(authUserName, password, true, true, true, true, authorities);
    }

    /**
     * 获取用户权限
     *
     * @param userMap 包含用户信息的 Map
     * @return 包含用户权限的 List
     */
    private List<GrantedAuthority> getUserAuthorities(Map<String, Object> userMap) {
        // 1.使用安全的类型转换方法获取用户菜单权限列表
        List<RouterVo> userMenuList = safeCast(userMap.get("userMenuList"), RouterVo.class);
        List<GrantedAuthority> menuAuthorities = userMenuList.stream()
                .map(routerVo -> new SimpleGrantedAuthority(routerVo.getMeta().toString()))
                .collect(Collectors.toList());
        // 2.使用安全的类型转换方法获取用户按钮权限列表
        List<String> userButtonList = safeCast(userMap.get("userButtonList"), String.class);
        List<GrantedAuthority> buttonAuthorities = userButtonList.stream()
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
        // 3.合并两个权限列表
        return Stream.concat(menuAuthorities.stream(), buttonAuthorities.stream()).toList();
    }

    // 类型安全的转换方法
    private <T> List<T> safeCast(Object object, Class<T> clazz) {
        if (object instanceof List<?>) {
            return ((List<?>) object).stream()
                    .filter(clazz::isInstance)
                    .map(clazz::cast)
                    .toList();
        }
        // 返回空列表而不是 null
        return List.of();
    }
}